using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
#if WECHAT_MINI_GAME
using WeChatWASM;
using static HotUpdateView;
#endif

public class HotUpdateView_WEBGNL : MonoBehaviour
{

#if WECHAT_MINI_GAME
    public string[] stateStr = {
        "检查资源版本","检查最新资源","检查本地资源","下载资源中","解压资源中"
    };

    protected Action<bool> successAction;

    protected Text label_tip;
    protected Text label_progress;
    protected Image img_progress_mask;
    protected Button btn_Reload;


    protected string versionPath = WX.env.USER_DATA_PATH + "/" + Const.VERSION_FILE_NAME;
    protected WXFileSystemManager wXFileSystemManager = WX.GetFileSystemManager();

    protected void Awake()
    {
        label_tip = this.transform.Find("label_tip").GetComponent<Text>();
        label_progress = this.transform.Find("label_progress").GetComponent<Text>();
        img_progress_mask = this.transform.Find("img_progress_bg/img_progress_mask").GetComponent<Image>();
        btn_Reload = this.transform.Find("btn_Reload").GetComponent<Button>();

        if (!Directory.Exists(Utils.GetLocalResLoadPath() + "/lua"))
        {
            Directory.CreateDirectory(Utils.GetLocalResLoadPath() + "/lua");
        }
    }

    protected void Start()
    {
        btn_Reload.onClick.AddListener(() => {
            if (Directory.Exists(Application.persistentDataPath))
            {
                Directory.Delete(Application.persistentDataPath, true);
                Application.Quit();
            }
        });
        this.HandlerHotUpdate();
    }


    public void HandlerHotUpdate()
    {
        if (Utils.GetIsLocal())
        {
            this.successAction(true);
            return;
        }
        StartCoroutine(GetVersion());
    }

    public void SetResCheckCallBack(Action<bool> p)
    {
        this.successAction = p;
    }

    //获得版本文件
    protected IEnumerator GetVersion()
    {
        this.label_tip.text = stateStr[0];
        var url = Const.RES_IP + Const.RES_PATH + Const.VERSION_FILE_NAME;
        UnityWebRequest webRequest = UnityWebRequest.Get(url);
        webRequest.timeout = 30;//设置超时，若webRequest.SendWebRequest()连接超时会返回，且isNetworkError为true

        yield return webRequest.SendWebRequest();

        if (webRequest.isNetworkError)
        {
                Debug.Log("Download Error:" + webRequest.error);
        }
        else
        {
            //本地已经有版本清单文件了 , 就删掉了
            //if (wXFileSystemManager.AccessSync(versionPath) != "access:ok")
            //{
            //    wXFileSystemManager.MkdirSync(versionPath);
            //}
            //玩家首次进入，就要开始拉全部资源了
            var bytes = webRequest.downloadHandler.data;
            wXFileSystemManager.WriteFileSync(versionPath, bytes.EncodeToString());
            var res = this.CheckNeedDownLoadRes();
            if (res.Count == 0)
            {
                //不用下载资源
                this.successAction(true);
            }
            else
            {
                //需要下载资源
                this.DownLoadAsset(res);
            }
        }
    }

    /// <summary>
    /// 拿到需要下载的资源列表
    /// </summary>
    /// <returns></returns>
    protected List<string> CheckNeedDownLoadRes()
    {
        //加载全部资源
        string xml_str = wXFileSystemManager.ReadFileSync(versionPath).EncodeToString();
        var xmlSerializer = new XmlSerializer(typeof(PackageVersion));

        StringReader sr = new StringReader(xml_str);
        XmlSerializer serializer = new XmlSerializer(typeof(PackageVersion));
        PackageVersion packageVersion = serializer.Deserialize(sr) as PackageVersion;
        sr.Dispose();

        GameData.gameVersion = packageVersion.version;
        Debug.LogError(packageVersion.version);
        //需要更新的新资源
        List<string> needUpdateRes = new List<string>();

        //检查清单文件
        var totalVersionNum = packageVersion.resList.Count;
        var index = 0;
        this.label_tip.text = stateStr[1];


        //远程最新的清单文件的数据  [资源名] = md5
        Dictionary<string, string> versionManifestDic = new Dictionary<string, string>();
        //本地当前资源的数据   [资源名] = "";
        Dictionary<string, string> localResDic = new Dictionary<string, string>();


        foreach (var resvo in packageVersion.resList)
        {
            SetProgress(index / totalVersionNum);
            Debug.LogError(resvo.resName);
            if (Utils.FindInString(resvo.resName, ".lua"))
            {
                versionManifestDic[resvo.resName] = resvo.md5Str;
            }
            index++;
        }

        index = 0;
        this.label_tip.text = stateStr[2];
        wXFileSystemManager.Stat(new WXStatOption
        {
            recursive = true,
            success = (succ) =>
            {
                totalVersionNum = succ.stats.Count;
                Debug.Log($"stat success");
                foreach (var file in succ.stats)
                {
                    path = WeChatWASM.WX.env.USER_DATA_PATH + file.path
                    SetProgress(index / totalVersionNum);
                    var name = Path.GetFileName(path);
                    Debug.LogError("Get File Name "+path + "   name :  " + name);
                    localResDic[name] = "";
                    if (versionManifestDic.ContainsKey(name))
                    {
                        string string_info = wXFileSystemManager.ReadFileSync(path);
                        var bytes = Encoding.UTF8.GetBytes(string_info);
                        //存在文件则检查MD5是否一致
                        if (Utils.GetMD5String(bytes) != versionManifestDic[name])
                        {
                            //MD5不一致 需要下载更新资源
                            needUpdateRes.Add(name);
                        }
                    }
                    else
                    {
                        //废弃资源 需要删除
                       // wXFileSystemManager.UnlinkSync(file.path);
                    }
                    index++;
                }
            }
        });
       



        foreach (var versionRes in versionManifestDic)
        {
            if (!localResDic.ContainsKey(versionRes.Key))
            {
                //不啦ICON的资源
                if (!Utils.FindInString(versionRes.Key, "icon_"))
                {
                    //本地没有这个资源 也去更新
                    needUpdateRes.Add(versionRes.Key);
                }
            }
        }

        return needUpdateRes;
    }


    public void DownLoadAsset(List<string> res)
    {
        this.label_tip.text = stateStr[3];
        SetProgress(0);
        var index = 0;
        foreach (var resName in res)
        {
            Debug.Log("本次更新这些文件 --->>> " + Const.RES_IP + Const.RES_PATH + resName);
            NetManager.Instance.AddAssetBundleRequest(Const.RES_IP + Const.RES_PATH + resName, (ab) =>
            {
                index++;
                var localPath = Utils.GetWechatABPath() + "/";
                Debug.LogError(ab);
                foreach (var luaFile in ab.LoadAllAssets<TextAsset>())
                {
                    var directoryName = resName.Replace("_", "/");
                    directoryName = directoryName.Replace(".lua", "");
                    var finalDireName = localPath + directoryName + "/";
                    if (Utils.FindInString(name, "lua_main"))
                    {
                        finalDireName = localPath + "lua/";
                    }

                    var mk_result = wXFileSystemManager.MkdirSync(finalDireName, true);
                    Debug.LogError("mk_result === >>  " + mk_result);

                    var fileName = luaFile.name.Replace(".bytes", ".lua") + ".lua";
                    Debug.Log(luaFile.name + "\n" + luaFile.text);
                    // if (!(Utils.IsFileExist(finalDireName + fileName) && Utils.GetMD5String(luaFile.bytes) == Utils.GetMD5String(bytes)))

                    //重新从AB包内加载lua
                    // File.WriteAllBytes(finalDireName + fileName, luaFile.bytes);
                    wXFileSystemManager.WriteFileSync(finalDireName + fileName, luaFile.text);
                }
                ab.Unload(true);
                SetProgress((float)index / res.Count);
                if (index == res.Count)
                {
                    this.successAction(true);
                }
                Thread.Sleep(50);
            });
        }
    }


    protected void SetProgress(float progress)
    {
        this.label_progress.text = ((progress / 1) * 100).ToString("0.00") + "%";
        this.img_progress_mask.fillAmount = progress / 1;
    }

    public void LoadAllLuaAsset(Action<bool> p)
    {
        this.label_tip.text = stateStr[4];
        p?.Invoke(true);
    }
#endif
}
